#include "PointEntry.h"

// 默认构造函数
PointEntry::PointEntry()
  : m_ID(0), m_ENTRY_NUM(0), m_point_entry(nullptr), m_status_entry(nullptr) {}

// 带参数的构造函数
PointEntry::PointEntry(int id, int entry_num)
  : m_ID(id), m_ENTRY_NUM(entry_num) {
  if (m_ENTRY_NUM <= 0) {
    throw std::invalid_argument("Entry number must be positive");
  }
  m_point_entry = new PointStruct*[m_ENTRY_NUM];
  m_status_entry = new bool[m_ENTRY_NUM];

  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    m_point_entry[i] = nullptr;
    m_status_entry[i] = false;
  }
}

// 析构函数
PointEntry::~PointEntry() {
  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    delete m_point_entry[i];
  }
  delete[] m_point_entry;
  delete[] m_status_entry;
}

// 添加 PointStruct
void PointEntry::addPoint(int index, PointStruct* point) {
  if (index < 0 || index >= m_ENTRY_NUM) {
    throw std::out_of_range("Index out of range");
  }
  if (m_point_entry[index] != nullptr) {
    delete m_point_entry[index];
  }
  m_point_entry[index] = point;
  m_status_entry[index] = true;
}

// 将 PointStruct 插入第一个空位
void PointEntry::pushPoint(PointStruct* point) {
  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    if (m_status_entry[i] == false) {
      m_point_entry[i] = point;
      m_status_entry[i] = true;
      return;
    }
  }
  throw std::overflow_error("No empty slots available to push a new point");
}

// 删除 PointStruct
void PointEntry::removePoint(int index) {
  if (index < 0 || index >= m_ENTRY_NUM) {
    throw std::out_of_range("Index out of range");
  }
  delete m_point_entry[index];
  m_point_entry[index] = nullptr;
  m_status_entry[index] = false;
}

// 获取非 false 的条目数量
int PointEntry::getPointNum() const {
  int count = 0;
  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    if (m_status_entry[i]) {
      ++count;
    }
  }
  return count;
}

// 获取 PointStruct
PointStruct* PointEntry::getPoint(int index) const {
  if (index < 0 || index >= m_ENTRY_NUM) {
    throw std::out_of_range("Index out of range");
  }
  if (m_point_entry[index] == nullptr) {
    throw std::runtime_error("No PointStruct at the specified index");
  }
  return m_point_entry[index]; // 返回指针，可以为 nullptr
}

// 获取并删除指定位置的 PointStruct
PointStruct* PointEntry::popPoint(int index) {
  if (index < 0 || index >= m_ENTRY_NUM) {
    throw std::out_of_range("Index out of range");
  }
  if (m_point_entry[index] == nullptr) {
    throw std::runtime_error("No PointStruct at the specified index");
  }
  PointStruct* point = m_point_entry[index];
  m_point_entry[index] = nullptr;
  m_status_entry[index] = false;
  return point; // 返回指针，调用者负责释放内存
}

// 打印状态
void PointEntry::printStatus() const {
  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    std::cout << "Entry " << i << ": ";
    if (m_point_entry[i]) {
      m_point_entry[i]->print();
    } else {
      std::cout << "Empty";
    }
    std::cout << " | Status: " << (m_status_entry[i] ? "Occupied" : "Empty") << std::endl;
  }
}

// 判断 Entry 中是否存在 z_crd 相同的 Point
bool PointEntry::hasSameZcrdPoint(const PointStruct& point) const {
  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    if (m_status_entry[i] && m_point_entry[i]->isSameZcrd(point)) {
      return true;
    }
  }
  return false;
}

// 根据传入的 Point 找到与之最接近的 Point，并从 Entry 中删除
PointStruct* PointEntry::findAndPopClosestPoint(const PointStruct& point, bool pop) {
  int closestIndex = -1;
  int bestMatchPriority = 4;  // 优先级：0 = z_crd, 1 = y_crd, 2 = x_crd，4 = 无匹配

  // 记录最佳匹配点的优先级（越小越优先）
  for (int i = 0; i < m_ENTRY_NUM; ++i) {
    if (m_status_entry[i]) { // not flase
      int matchPriority = 4;

      if (m_point_entry[i]->getZ() == point.getZ() and 
          m_point_entry[i]->getY() == point.getY() and
          m_point_entry[i]->getX() == point.getX()) {
        matchPriority = 0;  // 最优匹配
      } 
      else if (m_point_entry[i]->getZ() == point.getZ() and 
               m_point_entry[i]->getY() == point.getY()) {
        matchPriority = 1;
      } else if (m_point_entry[i]->getZ() == point.getZ()) {
        matchPriority = 2;
      }

      if (matchPriority < bestMatchPriority) {
        bestMatchPriority = matchPriority;
        closestIndex = i;
      }
    }
  }

  if (closestIndex == -1) {
    return nullptr;  // 没有找到匹配的点
  }

  // 找到匹配的点，将其从 Entry 中删除
  PointStruct* closestPoint = m_point_entry[closestIndex];
  if(pop) { popPoint(closestIndex); }
  return closestPoint;
}
